package com.kitty.game.gate;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.ServerService;

import com.kitty.game.role.model.Account;
import com.kitty.game.config.Server;
import com.kitty.game.gate.model.QueueUpService;
import com.kitty.game.role.service.AccountService;
import com.kitty.game.server.message.RespOtherLogin;
import com.kitty.mina.annotation.RequestMapping;
import com.kitty.mina.cache.DataCache;
import com.kitty.mina.codec.xf.StanUtils;
import com.kitty.mina.filter.ModuleCounterFilter;
import com.kitty.mina.message.MessagePusher;
import com.kitty.mina.session.SessionManager;
import com.kitty.mina.session.SessionProperties;
import org.apache.commons.lang3.time.StopWatch;
import org.apache.mina.core.session.IoSession;
import org.nutz.dao.Dao;
import org.nutz.lang.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;

import com.kitty.game.role.message.ReqKickOffClient;
import com.kitty.game.role.message.ReqLoginAccount;
import com.kitty.game.role.message.ReqRequestLineInfo;
import com.kitty.game.role.message.RespAgentResult;
import com.kitty.game.role.message.RespLoginWaitInLine;
import com.kitty.game.role.message.RespStartLogin;
import com.kitty.game.gate.message.LineData;
import com.kitty.game.gate.message.ReqGetCommunityAddress;
import com.kitty.game.gate.message.ReqLoginPreview;
import com.kitty.game.gate.message.ReqlineData;
import com.kitty.game.gate.message.RespGetCommunityAddress;
import com.kitty.game.gate.message.RespLoginPreview;
import com.kitty.game.gate.message.ResplineData;


@Controller
public class GateController {
    Logger logger = LoggerFactory.getLogger(GateController.class);

    @Autowired
    QueueUpService queueUpService;


//    private boolean isOpen(IoSession session, String sid) {
//        if (sid.contains("adminadmin")) {
//            return true;
//        }
//        ServerService serverService = SpringUtils.getBean(ServerService.class);
//        if (!serverService.isOpen()) {
//            RespOtherLogin respOtherLogin = new RespOtherLogin();
//            respOtherLogin.setContent("当前服务器限制登录。（原因：9030）");
//            respOtherLogin.setResult((short) 0);
//            MessagePusher.pushMessage(session, respOtherLogin);
//            return false;
//        }
//        return true;
//    }

    /**
     * 登录大区 网关调用
     * 请求排队信息
     *
     * @param session
     * @param request
     */
    @RequestMapping
    public void loginToDist(IoSession session, ReqRequestLineInfo request) {
        String ipAddr = ((InetSocketAddress)session.getRemoteAddress()).getAddress().getHostAddress();
        ServerService serverService = SpringUtils.getBean(ServerService.class);
//        if (serverService.getConcurrentHashMap().get(ipAddr) != null && System.currentTimeMillis() - serverService.getConcurrentHashMap().get(ipAddr) <= 30000) {
//            session.closeNow();
//            serverService.getConcurrentHashMap().put(ipAddr, System.currentTimeMillis());
//            logger.error("没有账号=11={}", ipAddr);
//            return;
//        }


        String sid = request.getAccountId().substring(6);
        if (sid.contains("-")){
            ModuleCounterFilter.banIp(session);
            return;
        }
        if (sid.length() != "00SgzcIo".length()){
            ModuleCounterFilter.banIp(session);
            return;
        }
        if (!SpringUtils.getRoleService().canLogin(sid,session)){
            return;
        }
        AccountService accountService = SpringUtils.getBean(AccountService.class);
//        ServerService serverService = SpringUtils.getBean(ServerService.class);
        Account account = accountService.getAccount(sid);

        /**帐号为空可能是第一次登录 这里需要去登录服取一下看看有没有这个帐号存在*/
        if(account==null){
            Map<String, Object> result = accountService.fetchAccountFromLoginServer(sid);
            if(result!=null){
                Object object = result.get("privilege");
                short privilege = 0;
                if (object != null){
                    privilege = new Integer((int)object).shortValue();
                }
                account =new Account(sid,result.get("username").toString(),result.get("channelCode").toString(), privilege);
                account.setPrivilege( privilege);
                account.setGold(0);
                account = accountService.addAccount(account);

            }
        }
        if (account == null || !account.getId().equals(sid)) {
            RespOtherLogin respOtherLogin = new RespOtherLogin();
            respOtherLogin.setContent("账号登录失败。（原因：9021）");
            respOtherLogin.setResult((short) 0);
            MessagePusher.pushMessage(session, respOtherLogin);
            ModuleCounterFilter.banIp(session);
//            session.closeNow();
//            serverService.getConcurrentHashMap().put(ipAddr,System.currentTimeMillis());
            logger.error("没有账号=={}",ipAddr);
            logger.error("没有账号=={}",request.getAccountId());
            return;
        }


        /**下面开始计算是否需要排队
         * 可以设置为服务器在线800人之后开始排队登录
         * 每人等待 5-10分钟
         * 然后每次请求这个协议排队时间减少相应的时间*/
        session.setAttribute(SessionProperties.ACCOUNT_SID, sid);
        /**如果需要排队 并且没有进入排队队列*/
        int index = queueUpService.getIndex(sid);
        if (account.getPrivilege()<=serverService.getNeice() && queueUpService.isNeedQueue() && index <= 0) {
            index = queueUpService.addQueue(sid);
            int waitTime = queueUpService.getQueueTime(sid);
            RespLoginWaitInLine respLoginWaitInLine = new RespLoginWaitInLine();
            respLoginWaitInLine.setWaitCode(index);
            respLoginWaitInLine.setExpect_time(waitTime);//排队时间 需要排队才设置
            String sonName = SpringUtils.getBean(ServerService.class).getServer().getSonName();
            respLoginWaitInLine.setLine_name(sonName);
            MessagePusher.pushMessage(session, respLoginWaitInLine);
        } else if (index > 0) {/**说明已经进入过排队的队列了*/
            /**是否能连接到线路了*/
            boolean canConnectLine = queueUpService.peek(sid);
            if (canConnectLine) {
                RespStartLogin respStartLogin = new RespStartLogin();
                respStartLogin.setCookie("4526387");
                respStartLogin.setType("normal");//登录的类型
                MessagePusher.pushMessage(session, respStartLogin);
            } else {
                int waitTime = queueUpService.getQueueTime(sid);
                RespLoginWaitInLine respLoginWaitInLine = new RespLoginWaitInLine();
                respLoginWaitInLine.setWaitCode(index);
                respLoginWaitInLine.setExpect_time(waitTime);//排队时间 需要排队才设置
                String sonName = SpringUtils.getBean(ServerService.class).getServer().getSonName();
                respLoginWaitInLine.setLine_name(sonName);
                MessagePusher.pushMessage(session, respLoginWaitInLine);
            }
        } else {/**如果不需要排队*/
            RespStartLogin respStartLogin = new RespStartLogin();
            respStartLogin.setCookie("4526387");
            respStartLogin.setType("normal");//登录的类型
            MessagePusher.pushMessage(session, respStartLogin);
        }
    }


    /**
     * 会员通道信息
     */
    @RequestMapping
    public void requestLineData(IoSession session, ReqlineData reqlineData) {
        ResplineData resplineData = new ResplineData();
        resplineData.setDatas(new ArrayList<>(Collections.singleton(new LineData())));
        LineData lineData = new LineData();
        lineData.setLine_name(SpringUtils.getBean(ServerService.class).getServer().getSonName());
        lineData.setExpect_time(500);
        resplineData.getDatas().add(lineData);
        MessagePusher.pushMessage(session, resplineData);

    }

    /**
     * 请求微社区地址
     */
    @RequestMapping
    public void requestAddr(IoSession session, ReqGetCommunityAddress communityAddress) {
        RespGetCommunityAddress respCommunityAddress = new RespGetCommunityAddress();
        respCommunityAddress.setAddr("http://vwd.leiting.com/#/index");
        MessagePusher.pushMessage(session, respCommunityAddress);
    }

    /**
     * 强制下线?
     */
//    @RequestMapping
//    public void kickOffClient(IoSession session, ReqKickOffClient offClient) {
//        logger.error("你已被强制下线");
//    }

    /**
     * 网关调用
     *
     * @param session
     //* @param reqLoginAccount
     */
    @RequestMapping
    public void kickOffClient(IoSession session, ReqKickOffClient offClient) {
        logger.error("你已被强制下线");
    }

    /**
     * 网关调用
     *
     * @param session
     * @param reqLoginAccount
     */
    @RequestMapping
    public void loginAccount(IoSession session, ReqLoginAccount reqLoginAccount) {
/*游戏维护*/
        ServerService serverService = SpringUtils.getBean(ServerService.class);
        if (ServerService.gate == 1){
            RespOtherLogin respOtherLogin = new RespOtherLogin();
            respOtherLogin.setContent("游戏维护中");
            respOtherLogin.setResult((short) 0);
            MessagePusher.pushMessage(session, respOtherLogin);
            ModuleCounterFilter.banIp(session);
            return;
        }

        if("cmd_l_login_preview_player".equals(reqLoginAccount.getType())){
            RespLoginPreview preview =new RespLoginPreview();
            preview.setCookie("4526387");
            preview.setSid(reqLoginAccount.getAccountId());
            MessagePusher.pushMessage(session,preview);
            session.closeNow();
            return;
        }
     //   ServerService serverService = SpringUtils.getBean(ServerService.class);
        String sid = SessionManager.INSTANCE.getSessionAttr(session, SessionProperties.ACCOUNT_SID, String.class);
        if (Strings.isEmpty(sid)) {
            RespOtherLogin respOtherLogin = new RespOtherLogin();
            respOtherLogin.setContent("账号登录失败。#r(原因：9023)");
            respOtherLogin.setResult((short) 0);
            MessagePusher.pushMessage(session, respOtherLogin);
            ModuleCounterFilter.banIp(session);
//            session.closeNow();
//            logger.error("没有账号异常==1111");
            return;
        }

        String deviceInfo = reqLoginAccount.getMac();
        AccountService accountService = SpringUtils.getBean(AccountService.class);
        Account account = accountService.getAccountNoCache(sid);
//        if (account == null) {
//            RespOtherLogin respOtherLogin = new RespOtherLogin();
//            respOtherLogin.setContent("账号登录失败。#r（原因：9024）");
//            respOtherLogin.setResult((short) 0);
//            MessagePusher.pushMessage(session, respOtherLogin);
//            ModuleCounterFilter.banIp(session);
////            session.closeNow();
////            logger.error("没有账号异常==222222");
//            return;
//        }
        /**如果是空密码代表第一次登录 写入请求的密码
         * 后面都是这个密码应该
         * 如果修改了登录服密码这个应该要清除掉  不知道加密方式只能这样了*/
        String ipAddr = "";
        try {
            ipAddr =session.getRemoteAddress().toString().split(":")[0].replace("/","");
            logger.error("登录IP:[{}]",ipAddr);
        }catch (Exception e){
        }
        account.setDeviceInfo(deviceInfo);
        SpringUtils.getBean(Dao.class).update(account, "deviceInfo");
        if (account.getIsStop() ==1) {
            RespOtherLogin respOtherLogin = new RespOtherLogin();
            respOtherLogin.setContent("运营中被封闭的帐号，请联系管理员。#r（原因：1033）");
            respOtherLogin.setResult((short) 2);
            MessagePusher.pushMessage(session, respOtherLogin);
//            ModuleCounterFilter.banIp(session);
//            session.closeNow();
//            logger.error("没有账号异常==22222");
            return;
        }
        if(!sid.startsWith("ww")){
            //黑名单验证
            if(accountService.isBanned(account.getId(), ipAddr, deviceInfo)) {
                RespOtherLogin respOtherLogin = new RespOtherLogin();
                respOtherLogin.setContent("登录失败。#r（原因：黑名单用户）");
                respOtherLogin.setResult((short) 0);
                MessagePusher.pushMessage(session, respOtherLogin);
                return;
            }

        }
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        /**目前直接返回第一个线路就行*/
        Server result = DataCache.ID_SERVER.values().stream().filter(server -> server.getIp().equals(serverService.getInetIp()) && server.getPort() == serverService.getPort()).findFirst().orElse(null);
        stopWatch.stop();
        if (result == null) {
            RespOtherLogin respOtherLogin = new RespOtherLogin();
            respOtherLogin.setContent("登录失败。#r（原因：1001）");
            respOtherLogin.setResult((short) 0);
            MessagePusher.pushMessage(session, respOtherLogin);
            ModuleCounterFilter.banIp(session);
//            session.closeNow();
//            logger.error("没有账号异常==33333");
            return;
        }

        /**允许登录*/
        LoginAuth request = new LoginAuth();
        int xorKey = StanUtils.calcXorKeyByOriginAuthKey(request.getAuthKey());
        DataCache.LOGIN_AUTHS.put(sid, request);
        RespAgentResult respAgentResult = new RespAgentResult();
      //  respAgentResult.setMsg("允许该账号登录");
//        respAgentResult.setPrivilege(account.getPrivilege());
//        respAgentResult.setPort((short) result.getSonPort());
//        respAgentResult.setAuth_key(request.getAuthKey());
        //respAgentResult.setSeed(request.getSeed());
       // respAgentResult.setAuth_key(request.getAuthKey());
       // respAgentResult.setResult(1 ^ xorKey);
        // 数据库获取GM权限   去掉客户端的gm按钮
        respAgentResult.setPrivilege(account.getPrivilege() >= 100 ? account.getPrivilege() : 0);   //0原先等于10
        respAgentResult.setIp(result.getSonIp());
        respAgentResult.setPort((short) (8948 ^ result.getSonPort()));


       // respAgentResult.setSeed(request.getSeed());
      //  respAgentResult.setResult(1 ^ xorKey);
        respAgentResult.setServerName(result.getSonName());
        respAgentResult.setServerStatus((byte) 2);
        respAgentResult.setMsg("允许该账号登录");
        //logger.error("允许该账号登陆=={}{}",(short) (xorKey ^ result.getSonPort()),respAgentResult.toString());



//        ////////////////////////////////////
        respAgentResult.setAuth_key(0);
//        respAgentResult.setResult(1 ^ xorKey);
        respAgentResult.setResult(1);
        respAgentResult.setPrivilege((short) account.getPrivilege() >= 100 ? account.getPrivilege() : 0); //????
        respAgentResult.setIp(result.getSonIp());
        respAgentResult.setPort((short) (result.getSonPort()));
        respAgentResult.setSeed(0);

        respAgentResult.setServerName(result.getSonName());
        MessagePusher.pushMessage(session, respAgentResult);
    }




    @RequestMapping
    public void previewLogin(IoSession session ,ReqLoginPreview preview){
        RespStartLogin respStartLogin = new RespStartLogin();
        respStartLogin.setCookie("4526387");
        respStartLogin.setType("cmd_l_login_preview_player");//登录的类型
        MessagePusher.pushMessage(session, respStartLogin);
    }
}
